package org.jiucai.app.admin;

import java.io.IOException;
import java.io.PrintWriter;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.jiucai.app.AppBaseController;
import org.jiucai.app.demo.helper.AppHelper;
import org.jiucai.appframework.base.spring.service.IBinaryService;
import org.jiucai.appframework.base.spring.service.IDataService;
import org.jiucai.appframework.base.spring.service.IDownloadService;
import org.jiucai.appframework.base.spring.service.IPageService;
import org.jiucai.appframework.base.spring.service.IUploadService;
import org.jiucai.appframework.common.util.EscapeUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartHttpServletRequest;

@Controller
@RequestMapping(value = "/admin")
public class AdminDefaultController extends AppBaseController{

	/**
	 * Request 请求中的 服务ID 参数名
	 */
	private static final String REQ_SID = "sid";
	
	/**
	 * 页面请求
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@RequestMapping(value = "/p")
	public String page(Map<String, Object> model, HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
		String errorMsg = "";

		String templatePage = "error/report_error";
		Boolean errFlag = false;
		IPageService service = null;
		
		Map<String, Object> reqParam = AppHelper.parseRequest(request);
		String serviceId = (String) reqParam.get(REQ_SID);
		
		if (null != serviceId) {
			try {
				ApplicationContext context = AppHelper.getApplicationContext(request);
				service = context.getBean(serviceId + "PageService",IPageService.class);
				if (null != service) {
					templatePage = service.handleRequest(reqParam, model);
				} else {
					errFlag = true;
					errorMsg = "service " + serviceId + " not exists.";
				}
			} catch (Exception e) {
				log.error(ExceptionUtils.getFullStackTrace(e));
				String errMsg = ExceptionUtils.getRootCauseMessage(e);
				if (null != errMsg && errMsg.length() > 2) {
					String[] msgs = errMsg.split(":");
					if (null != msgs && msgs.length > 1) {
						errMsg = msgs[1].trim();
					}
				}
				errFlag = true;
				errorMsg = "service " + serviceId + " failed: " + errMsg;
			}
		} else {
			errFlag = true;
			errorMsg = "service id is required.";
		}
		if (errFlag) {
			log.error("page service failed: " + errorMsg);
			model.put("errorMsg", "系统忙，请稍后再试。");
		}
		return templatePage;
	}
	
	/**
	 * 数据请求
	 * 
	 * @param model
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@RequestMapping(value = "/d")
	public void data(Map<String, Object> model, HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String resultData = null;
		String contentType = "application/json; charset=UTF-8";
		String dataType = IDataService.DATA_TYPE_JSON;
		Map<String, Object> reqParam = AppHelper.parseRequest(request);
		String serviceId = (String) reqParam.get(REQ_SID);
		Boolean errFlag = false;
		if (null != serviceId) {
			ApplicationContext context = AppHelper.getApplicationContext(request);
			IDataService service = null;
			try {
				service = context.getBean(serviceId + "DataService",IDataService.class);
				if (null != service) {
					resultData = service.handleRequest(reqParam);
					contentType = service.getContentType(reqParam);
				} else {
					errFlag = true;
					resultData = formatMsg(dataType, "service " + serviceId + " not exists.");
				}
			} catch (Exception e) {
				log.error("dataService failed: " + ExceptionUtils.getFullStackTrace(e));
				String errMsg = ExceptionUtils.getRootCauseMessage(e);
				if (null != errMsg && errMsg.length() > 2) {
					String[] msgs = errMsg.split(":");
					if (null != msgs && msgs.length > 1) {
						errMsg = msgs[1].trim();
					}
				}
				errFlag = true;
				resultData = formatMsg(dataType, "service " + serviceId + " failed: " + errMsg);
			}
		} else {
			errFlag = true;
			resultData = formatMsg(dataType, "service id is required.");
		}
		if (errFlag) {
			log.error("data service failed: " + resultData);
		}
		output(response, resultData, contentType);
	}
	
	private String formatMsg(String fmt, String data) {
		String result = data;
		if (IDataService.DATA_TYPE_JSON.equalsIgnoreCase(fmt)) {
			result = new StringBuffer("{\"error\": \"").append(EscapeUtil.escape(data)).append("\"}").toString();
		} else if (IDataService.DATA_TYPE_XML.equalsIgnoreCase(fmt)) {
			result = new StringBuffer("<error>").append(EscapeUtil.escape(data)).append("<error>").toString();
		} else {
			// default
		}
		return result;
	}

	private void output(HttpServletResponse response, String msg, String contentType) {
		PrintWriter out = null;
		try {
			// 必须放在 response.getWriter(); 之前否则不起作用
			response.setHeader("Content-Type", contentType);
			response.setHeader("Pragma", "no-cache");
			response.addHeader("Cache-Control", "must-revalidate");
			response.addHeader("Cache-Control", "no-cache");
			response.addHeader("Cache-Control", "no-store");
			response.setDateHeader("Expires", 0);
			out = response.getWriter();
			if(null != out ){
				if(null == msg){
					msg = "";
				}
				out.write(msg);
			}
		} catch(Exception e){
			log.error("output failed: " + ExceptionUtils.getFullStackTrace(e));
		}finally {
			if (null != out) {
				out.close();
			}
		}
	}
	
	/**
	 * 下载请求
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@RequestMapping(value = "/upload")
	public void upload(MultipartHttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		String resultData = null;
		String contentType = "application/json; charset=UTF-8";
		String dataType = IDataService.DATA_TYPE_JSON;
		Map<String, Object> reqParam = AppHelper.parseRequest(request);
		String serviceId = (String) reqParam.get(REQ_SID);
		Boolean errFlag = false;

		if (null != serviceId) {
			ApplicationContext context = AppHelper.getApplicationContext(request);
			IUploadService service = null;
			try {
				service = context.getBean(serviceId + "UploadService",
						IUploadService.class);

				if (null != service) {
					resultData = service.handleRequest(reqParam, request);
					contentType = service.getContentType(reqParam);
				} else {
					errFlag = true;
					resultData = formatMsg(dataType, "service " + serviceId
							+ " not exists.");
				}

			} catch (Exception e) {
				String errMsg = ExceptionUtils.getRootCauseMessage(e);
				if (null != errMsg && errMsg.length() > 2) {
					String[] msgs = errMsg.split(":");
					if (null != msgs && msgs.length > 1) {
						errMsg = msgs[1].trim();
					}
				}
				errFlag = true;
				resultData = formatMsg(dataType, "service " + serviceId
						+ " failed: " + errMsg);
			}

		} else {
			errFlag = true;
			resultData = formatMsg(dataType, "service id is required.");

		}
		
		if (errFlag) {
			log.error("upload service failed: " + resultData);
		}

		output(response, resultData, contentType);

	}

	/**
	 * 下载请求
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@RequestMapping(value = "/download")
	public void download(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String errorMsg = "";
		Map<String, Object> reqParam = AppHelper.parseRequest(request);
		String serviceId = (String) reqParam.get(REQ_SID);
		Boolean errFlag = false;
		String fileName = null;
		Boolean isFileExists = false;

		if (null != serviceId) {
			ApplicationContext context = AppHelper.getApplicationContext(request);
			IDownloadService service = null;
			try {
				service = context.getBean(serviceId + "DownloadService",IDownloadService.class);

				if (null != service) {

					fileName = service.getFileName(reqParam);
					isFileExists = service.fileExists(reqParam);

					log.info("download file name:" + fileName);
					
					if(isFileExists && StringUtils.isNotBlank(fileName)){
						
						//下载的文件名中不能包含空格，否则浏览器无法解析
						fileName = fileName.trim().replace(" ", "");
						
						if (request.getHeader("User-Agent").toUpperCase().indexOf("MSIE") > 0) {
							fileName = URLEncoder.encode(fileName, "UTF-8");// IE浏览器
						} else {
							fileName = new String(fileName.getBytes("UTF-8"),"ISO8859-1");// 非IE浏览器
						}
						
						response.setContentType(service.getContentType(reqParam));

						response.addHeader("Cache-Control", "must-revalidate");
						response.addHeader("Cache-Control", "no-cache");
						response.addHeader("Cache-Control", "no-store");

						response.setDateHeader("Expires", 0);

						response.setHeader("Pragma", "no-cache");
						response.setHeader("Connection", "close");

						response.setHeader("Content-Disposition","attachment;filename=" + fileName);

						service.handleRequest(reqParam, response.getOutputStream());
		
					}else{
						errFlag = true;
						errorMsg = "file not exists or download file name is null.";
						response.sendError(HttpServletResponse.SC_NOT_FOUND,errorMsg);
						return;
					}
					
					

					
				} else {
					errFlag = true;
					errorMsg = "service " + serviceId + " not exists.";
				}

			} catch (Exception e) {
				
				log.error("文件下载失败: " + ExceptionUtils.getFullStackTrace(e));

				String errMsg = ExceptionUtils.getRootCauseMessage(e);
				if (null != errMsg && errMsg.length() > 2) {
					String[] msgs = errMsg.split(":");
					if (null != msgs && msgs.length > 1) {
						errMsg = msgs[1].trim();
					}
				}
				errFlag = true;
				errorMsg = "service " + serviceId + " failed: " + errMsg;
			}

		} else {
			errFlag = true;
			errorMsg = "service id is required.";
		}

		if (errFlag) {
			log.error("download service failed: " + errorMsg);
			
			request.setAttribute("failed_msg", "请求的文件不存在或已经被删除。");
			//request.getRequestDispatcher("/common/error/session_failed.jsp").forward(request, response);
			
			
			String path = request.getContextPath();
			String basePath = new StringBuffer(request.getScheme()).append("://").append(request.getServerName()).append(":").append(request.getServerPort()).append(path).toString();
			
			response.sendRedirect(basePath + "/common/error/session_failed.jsp");
			return;
		}

	}
	
	
	/**
	 * 二进制请求
	 * 
	 * @param request
	 * @param response
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	@RequestMapping(value = "/binary")
	public void binary(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {
		String errorMsg = "";
		Map<String, Object> reqParam = AppHelper.parseRequest(request);
		String serviceId = (String) reqParam.get(REQ_SID);
		Boolean errFlag = false;
		Boolean isFileExists = false;

		if (null != serviceId) {
			ApplicationContext context = AppHelper.getApplicationContext(request);
			IBinaryService service = null;
			try {
				service = context.getBean(serviceId + "BinaryService",IBinaryService.class);

				if (null != service) {

					isFileExists = service.fileExists(reqParam);

					
					if(isFileExists){


						response.addHeader("Cache-Control", "must-revalidate");
						response.addHeader("Cache-Control", "no-cache");
						response.addHeader("Cache-Control", "no-store");

						response.setDateHeader("Expires", 0);

						response.setHeader("Pragma", "no-cache");
						response.setHeader("Connection", "close");

						service.handleRequest(reqParam, response.getOutputStream());
		
					}else{
						errFlag = true;
						errorMsg = "file not exists.";
						
						response.sendError(HttpServletResponse.SC_NOT_FOUND,errorMsg);
						return;
					}
					
					

					
				} else {
					errFlag = true;
					errorMsg = "service " + serviceId + " not exists.";
				}

			} catch (Exception e) {
				
				log.error("文件读取失败: " + ExceptionUtils.getFullStackTrace(e));

				String errMsg = ExceptionUtils.getRootCauseMessage(e);
				if (null != errMsg && errMsg.length() > 2) {
					String[] msgs = errMsg.split(":");
					if (null != msgs && msgs.length > 1) {
						errMsg = msgs[1].trim();
					}
				}
				errFlag = true;
				errorMsg = "service " + serviceId + " failed: " + errMsg;
			}

		} else {
			errFlag = true;
			errorMsg = "service id is required.";
		}

		if (errFlag) {
			log.error("binary service failed: " + errorMsg);
			
			request.setAttribute("failed_msg", "请求的文件不存在或已经被删除。");
			//request.getRequestDispatcher("/common/error/session_failed.jsp").forward(request, response);
			
			
			String path = request.getContextPath();
			String basePath = new StringBuffer(request.getScheme()).append("://").append(request.getServerName()).append(":").append(request.getServerPort()).append(path).toString();
			
			response.sendRedirect(basePath + "/common/error/session_failed.jsp");
			return;
		}

	}
}
